package cn.sc.summer.construction.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import cn.sc.summer.constant.enums.StatusEnum;
import cn.sc.summer.constant.project.DateConstant;
import cn.sc.summer.constant.token.TokenConstant;
import cn.sc.summer.constant.util.AssertUtil;
import cn.sc.summer.constant.util.ConvertUtil;
import cn.sc.summer.daoapi.dao.SysApiRouteMapper;
import cn.sc.summer.daoapi.dao.SysRouteMapper;
import cn.sc.summer.daoapi.dao.SysTenantInfoMapper;
import cn.sc.summer.daoapi.dao.SysUserInfoMapper;
import cn.sc.summer.daoapi.po.SysApiRoute;
import cn.sc.summer.daoapi.po.SysRoute;
import cn.sc.summer.daoapi.po.TenantInfo;
import cn.sc.summer.domain.service.SysTenantInfoService;
import cn.sc.summer.exception.exceptions.CommonException;
import cn.sc.summer.mybatis.mapper.SysApiMapper;
import cn.sc.summer.mybatis.po.SysApi;
import cn.sc.summer.protocol.form.SysTenantInfoForm;
import cn.sc.summer.protocol.vo.TenantInfoVO;
import cn.sc.summer.redis.util.RedisHelper;
import cn.sc.summer.token.po.SysUserInfo;
import cn.sc.summer.token.util.AESUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 类名：区域信息接口实现业务层
 *
 * @author a-xin
 * @date 2023/9/8 14:13
 */
@Service
public class SysTenantInfoServiceImpl implements SysTenantInfoService {

    @Value("${user.name:admin}")
    private String NAME;

    @Value("${user.password:Aa@123456}")
    private String PASSWORD;

    @Resource
    private SysTenantInfoMapper sysTenantInfoMapper;

    @Resource
    private SysUserInfoMapper sysUserInfoMapper;

    @Resource
    private SysRouteMapper sysRouteMapper;

    @Resource
    private SysApiMapper sysApiMapper;

    @Resource
    private SysApiRouteMapper sysApiRouteMapper;

    /**
     * 接口: 新增区域信息
     *
     * @param form 数据提交表单
     * @return cn.sc.summer.daoapi.po.TenantInfo
     * @author a-xin
     * @date 2023/9/8 14:17
     */
    @Override
    public TenantInfoVO addTenant(SysTenantInfoForm form) {

        Optional.ofNullable(sysTenantInfoMapper.selectOne(new LambdaQueryWrapper<TenantInfo>()
                .eq(true, TenantInfo::getName, form.getName()))).ifPresent(tenantInfo -> {
            throw new CommonException("已存在相同名称的区域！");
        });

        String userId = IdWorker.getIdStr();
        String tenantId = IdWorker.getIdStr();

        String randomKey = RandomUtil.randomString(16);
        SysUserInfo sysUserInfo = new SysUserInfo();
        sysUserInfo.setId(IdWorker.getIdStr());
        sysUserInfo.setName(NAME)
                .setAge(100)
                .setAcesskey(randomKey)
                .setPassWord(AESUtil.encrypt(PASSWORD, randomKey))
                .setPhone(form.getContactTel())
                .setCreateUser(userId)
                .setUpdateUser(userId)
                .setId(userId)
                .setDataTenantId(tenantId);
        sysUserInfoMapper.insert(sysUserInfo);
        Map<String, Object> userInfoMap = ConvertUtil.convertToMap(sysUserInfo);
        userInfoMap.put("updateTime", DateUtil.format(sysUserInfo.getUpdateTime(), DateConstant.YYYY_MM_DD_HH_MM_SS_1));
        userInfoMap.put("createTime", DateUtil.format(sysUserInfo.getCreateTime(), DateConstant.YYYY_MM_DD_HH_MM_SS_1));
        userInfoMap.remove("acesskey");
        RedisHelper.hmSet(TokenConstant.USER_INFO + sysUserInfo.getId(), userInfoMap);

        TenantInfo tenantInfo = new TenantInfo();
        tenantInfo.setId(tenantId);
        tenantInfo.setName(form.getName())
                .setContactName(sysUserInfo.getName())
                .setContactTel(form.getContactTel())
                .setContactUserId(userId)
                .setDataTenantId(tenantId)
                .setCreateUser(userId)
                .setUpdateUser(userId);
        sysTenantInfoMapper.insert(tenantInfo);

        String routeId = IdWorker.getIdStr();
        SysRoute sysRoute = new SysRoute();
        sysRoute.setId(routeId);
        sysRoute.setRoute("/project")
                .setLft(1)
                .setRgt(2)
                .setName("管理员Route")
                .setPId("-1")
                .setOpen(StatusEnum.ENABLE_OR_NOT_DELETED.getType())
                .setCode("PROJECT")
                .setDataTenantId(tenantId)
                .setCreateUser(userId)
                .setUpdateUser(userId);
        sysRouteMapper.insert(sysRoute);

        List<SysApi> sysApis = sysApiMapper.selectList();
        AssertUtil.functionIfPre(sysApis, CollUtil::isNotEmpty, () -> {
            List<SysApiRoute> sysApiRoutes = sysApis.stream().map(sysApi -> {
                SysApiRoute sysApiRoute = new SysApiRoute();
                sysApiRoute.setApiId(sysApi.getId())
                        .setRouteId(routeId)
                        .setDataTenantId(tenantId)
                        .setCreateUser(userId)
                        .setUpdateUser(userId);
                return sysApiRoute;
            }).collect(Collectors.toList());
            sysApiRouteMapper.insertBatchSomeColumn(sysApiRoutes);
        });

        TenantInfoVO tenantInfoVO = new TenantInfoVO();
        BeanUtils.copyProperties(tenantInfo, tenantInfoVO);

        return tenantInfoVO;
    }
}
